package com.runvp.common.util.sms;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;


/**
 * 短信发送
 *@author xukk_dp
* @email:zhangxin@champion-credit.com
* @version: 1.0
*/
public class GmUtils {

    public static Cipher sm4CbcPkcs7PaddingCipher;
    public static Cipher sm4EcbPkcs7PaddingCipher;
    public static byte[] sm4Encrypt(byte[] input, byte[] key, byte[] iv)
            throws Exception {
        return sm4(input, key, iv, 1);
    }
    public static String sm4Encrypt(String input, String key) {
        try {
            return Hex.encodeHexString(sm4Encrypt(input.getBytes(),
                    Hex.decodeHex(key.toCharArray()), null));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static byte[] sm4Decrypt(byte[] input, byte[] key, byte[] iv)
            throws Exception {
        return sm4(input, key, iv, 2);
    }
    public static String sm4Decrypt(String input, String key) throws
            Exception {
        return new String(sm4Decrypt(Hex.decodeHex(input.toCharArray()),
                Hex.decodeHex(key.toCharArray()), null));
    }
    private static byte[] sm4(byte[] input, byte[] key, byte[] iv, int mode) throws Exception {
        IvParameterSpec ivParameterSpec = null;
        if (iv != null) {
            ivParameterSpec = new IvParameterSpec(iv);
        }
        SecretKeySpec sm4Key = new SecretKeySpec(key, "SM4");
        if (ivParameterSpec == null) {
            sm4EcbPkcs7PaddingCipher.init(mode, sm4Key);
            return sm4EcbPkcs7PaddingCipher.doFinal(input);
        }
        sm4CbcPkcs7PaddingCipher.init(mode, sm4Key, ivParameterSpec);
        return sm4CbcPkcs7PaddingCipher.doFinal(input);
    }
    static {
        Security.addProvider(new BouncyCastleProvider());
        try {
            sm4CbcPkcs7PaddingCipher =
                    Cipher.getInstance(SM4ModeAndPaddingEnum.SM4_CBC_PKCS7Padding.getName(),
                            "BC");
            sm4EcbPkcs7PaddingCipher =
                    Cipher.getInstance(SM4ModeAndPaddingEnum.SM4_ECB_PKCS7Padding.getName(),
                            "BC");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }
    public static enum SM4ModeAndPaddingEnum {
        SM4_ECB_NoPadding("SM4/ECB/NoPadding"),
        SM4_ECB_PKCS5Padding("SM4/ECB/PKCS5Padding"),
        SM4_ECB_PKCS7Padding("SM4/ECB/PKCS7Padding"),
        SM4_CBC_NoPadding("SM4/CBC/NoPadding"),
        SM4_CBC_PKCS5Padding("SM4/CBC/PKCS5Padding"),
        SM4_CBC_PKCS7Padding("SM4/CBC/PKCS7Padding");
        private String name;
        private SM4ModeAndPaddingEnum(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
    }
}
